home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Graphics
/
MapMaker
/
Source
/
pointdata.c
< prev
next >
Wrap
Text File
|
1990-12-04
|
6KB
|
342 lines
#import <stdio.h>
#import <stdlib.h>
#import "pointdata.h"
#import "appkit/graphics.h"
#import <math.h>
/* This is pointdata.c. */
void newPointList(PointList *p)
{
p->head = NULL;
p->tail = NULL;
p->quantity = 0;
}
void freePointList(PointList *p)
{
pointNode *t;
for(t=p->head;(t);t=p->head) {
p->head = p->head->next;
free(t);
}
p->head = NULL;
p->tail = NULL;
p->quantity = 0;
}
int addBlockTo(PointList *p)
{
p->tail->next = (pointNode *)malloc(sizeof(pointNode));
if (!(p->tail->next))
return 0;
p->tail = p->tail->next;
p->tail->contains = 0;
p->tail->next = NULL;
return 1;
}
int addStartBlockTo(PointList *p)
{
p->head = p->tail = (pointNode *)malloc(sizeof(pointNode));
if (!(p->head))
return 0;
p->head->contains = 0;
p->head->next = NULL;
return 1;
}
void addPointTo(PointList *p, Point *pt)
{
int r;
/* Requires that p->tail not be full!!!!!! */
r = p->tail->contains;
p->tail->block[r].x = pt->x;
p->tail->block[r].y = pt->y;
p->tail->block[r].pen = pt->pen;
p->tail->block[r].pencolour = pt->pencolour;
p->tail->contains++;
}
int addToPointList(PointList *p, Point *pt)
{
if (pt->pen == SKIP)
return 1;
if (p->tail) { /* normal case */
if (p->tail->contains >= BLOCKSIZE)
if (!(addBlockTo(p)))
return 0;
addPointTo(p,pt);
} else { /* first point added. */
if (!(addStartBlockTo(p)))
return 0;
addPointTo(p,pt);
}
p->quantity++;
return 1;
}
void eliminate(pointBlock b,int size, int index)
{
int i;
for(i=index;(i<(size-1));i++)
b[i] = b[i+1];
}
int removeFromPointList(PointList *p,int index)
{
pointNode *s,*g;
int sum = 0;
int t = 1;
g = NULL;
if (index >= p->quantity)
return 0;
for(s = p->head;((s) && (t));) {
sum = sum + s->contains;
if (index < sum)
t = 0;
else {
g = s;
s=s->next;
}
}
if (s)
if (s->contains == 1) {
if (g) {
g->next = s->next;
if (!(g->next))
p->tail = g;
} else {
p->head = s->next;
if (!(s->next))
p->tail = NULL;
}
free(s);
} else
eliminate(s->block,s->contains,(index - (sum - s->contains)));
else
return 0;
s->contains--;
p->quantity--;
return 1;
}
void insertpointat(pointBlock b, int index, int size, Point *pt)
{
int i;
if (size >= BLOCKSIZE)
size = BLOCKSIZE -1;
for(i = size;(i>index);i--)
b[i] = b[i-1];
b[index] = *pt;
}
int insertInPointListAt(PointList *p,Point *pt, int index)
{
pointNode *s, *g;
int sum = 0;
int t = 1;
int base;
if (pt->pen == SKIP)
return 1;
if (index > p->quantity)
return 0;
if (index == p->quantity)
return addToPointList(p,pt);
for(s = p->head;(t);) {
sum = sum + s->contains;
if (index < sum)
t = 0;
else {
g = s;
s= s->next;
}
}
if (s) {
base = sum - s->contains;
if (s->contains == BLOCKSIZE) { /* can't insert to s->block (cause it's full.) */
if (s->next) { /* another node exists */
if (s->next->contains == BLOCKSIZE) {/* can't do next node either. */
/* so we insert a node. */
g = s->next;
s->next = (pointNode *)malloc(sizeof(pointNode));
if (!(s->next))
return 0;
s->next->block[0] = s->block[(BLOCKSIZE-1)];
s->next->next = g;
s->next->contains = 1;
insertpointat(s->block,(index-base),(s->contains),pt);
} else {
insertpointat(s->next->block,0,s->next->contains,&(s->block[BLOCKSIZE-1]));
insertpointat(s->block,(index-base),s->contains,pt);
(s->next->contains)++;
}
} else { /* s is full, s is tail. */
g = (pointNode *)malloc(sizeof(pointNode));
if (!(g))
return 0;
g->block[0] = s->block[(BLOCKSIZE-1)];
g->contains = 1;
g->next = NULL;
s->next = g;
p->tail = g;
insertpointat(s->block,(index-base),s->contains,pt);
}
} else { /* ok to insert to s->block. */
insertpointat(s->block,(index-base),s->contains,pt);
(s->contains)++;
}
} else
return 0;
p->quantity++;
return 1;
}
int gotoPointInList(PointList *p,int index,Point **pt)
{
int total = 0;
pointNode *n;
int t=1;
int base;
if ((index >= p->quantity) || (index <0))
return 0;
for(n=p->head;(t);) {
total = total + n->contains;
if (total > index)
t = 0;
else
n = n->next;
}
base = total - n->contains;
*pt = &(n->block[(index-base)]);
p->curr = n;
p->currpos = (index-base);
p->currtot = index;
return 1;
}
int gotoNextPointInList(PointList *p, Point **pt)
{
if (p->currtot >= (p->quantity-1))
return 0;
if ((p->currpos+1) == p->curr->contains) {
p->curr = p->curr->next;
if (!(p->curr))
return 0;
else {
p->currpos = 0;
*pt = &(p->curr->block[0]);
}
} else {
if (!(p->curr))
return 0;
*pt = &(p->curr->block[++(p->currpos)]);
}
p->currtot++;
return 1;
}
int lastPointInList(PointList *p, Point **pt)
{
if (p->quantity == 0)
return 0;
*pt = &(p->tail->block[p->tail->contains-1]);
return 1;
}
void doTestShape(PointList *p)
{
Point pt;
pt.pencolour = NX_BLACK;
pt.pen = DOWN;
pt.x = 0.3;
pt.y = 0.3;
addToPointList(p,&pt);
pt.x = -0.3;
addToPointList(p,&pt);
pt.y = -0.3;
addToPointList(p,&pt);
pt.x = 0.3;
addToPointList(p,&pt);
pt.y = -0.1;
addToPointList(p,&pt);
pt.x = 0.1;
pt.pen = UP;
addToPointList(p,&pt);
}
int savePointList(PointList *p,char *fn)
{
FILE *fp;
int t;
Point *pt;
/* attempt to write the PointList. */
fp = fopen(fn,"w");
if (fp) {
for(t=gotoPointInList(p,0,&pt);t;t=gotoNextPointInList(p,&pt))
fprintf(fp,"%f %f %d %f\n",pt->x,pt->y,pt->pen,pt->pencolour);
fclose(fp);
return 1;
} else
return 0;
}
int loadPointList(PointList *p,char *fn)
{
FILE *fp;
Point pt;
int t;
fp = fopen(fn,"r");
if (fp) {
for(t = fscanf(fp,"%f %f %d %f\n",&(pt.x),&(pt.y),&(pt.pen),&(pt.pencolour)); (t == 4);
t = fscanf(fp,"%f %f %d %f\n",&(pt.x),&(pt.y),&(pt.pen),&(pt.pencolour)))
addToPointList(p,&pt);
fclose(fp);
return 1;
} else
return 0;
}
int nearestPointInList(PointList *p,Point **pt,float x,float y,int *index)
{
int s;
Point *pt2;
float dist,mindist;
int counter;
if (p->quantity == 0)
return 0;
counter = 0;
s = gotoPointInList(p,0,&pt2);
mindist = ((x - pt2->x) * (x - pt2->x)) + ((y - pt2->y) * (y - pt2->y));
*pt = pt2;
*index = counter;
for(s=gotoNextPointInList(p,&pt2);s;s=gotoNextPointInList(p,&pt2)) {
counter++;
dist = (((x - pt2->x) * (x - pt2->x)) + ((y - pt2->y) * (y - pt2->y)));
if (dist < mindist) {
*pt = pt2;
*index = counter;
mindist = dist;
}
}
return 1;
}